﻿using System;
using System.Linq;
using WordNet.Core;
using WordNet.Core.ElementContracts;
using WordNet.Core.Morphy;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace WordNet.CoreTests.Morphy
{
    [TestClass]
    public class MorphyUnitTest
    {
        [TestMethod]
        public void CanCreateStemmingRuleTest()
        {
            IStemmingRule sr = new StemmingRule("xxx", "yyy", POS.VERB, "aa", "cc");
            Assert.IsNotNull(sr);
            Assert.IsInstanceOfType(sr, typeof( IStemmingRule));
            Assert.AreEqual<string>("xxx", sr.GetSuffix());
            Assert.AreEqual<string>("yyy", sr.GetEnding());
            Assert.AreEqual<POS>(POS.VERB, sr.PartOfSpeech);
            Assert.IsTrue(sr.GetSuffixIgnoreSet().Contains("aa"));
            Assert.IsTrue(sr.GetSuffixIgnoreSet().Contains("cc"));
        }

        [TestMethod]
        public void CanReplaceSuffixWithEnding()
        {
            // create rule: stripp "xxx" from a word and add ending "yyy"
            IStemmingRule sr = new StemmingRule("xxx", "yyy", POS.VERB);
            string targerWord = "adfaxxx";
            Assert.AreEqual<string>("adfayyy", sr.ApplyTo(targerWord));
        }
      
        [TestMethod]
        public void CanExpandAbraviation()
        {
            // create rule: stripp "." from a word and replace it with "ober"
            IStemmingRule sr = new StemmingRule(".", "ober", POS.NOUN);
            Assert.AreEqual<string>("october", sr.ApplyTo("oct."));

        }

        [TestMethod]
        public void CanIgnoreSpecyfiedSuffixes()
        {
            // create rule: replace "s" with "" if a word is not ending with "ss" or "xs" 
             IStemmingRule sr = new StemmingRule("s", "", POS.NOUN, "ss", "xs");
             Assert.AreEqual<string>("aaa", sr.ApplyTo("aaas"));
             Assert.AreEqual<string>(null, sr.ApplyTo("aaass"));
             Assert.AreEqual<string>(null, sr.ApplyTo("aaaxs"));
        }

         [TestMethod]
         public void CanAppendOptinalSuffix()
         {
             IStemmingRule sr = new StemmingRule("zz", "", POS.NOUN);
             Assert.AreEqual<string>("aaaopt", sr.AddSuffixToEnd("aaazz", "opt"));
         }
       
        [TestMethod]
        public void CanCreateSimpleStemmer()
        {
            SimpleStemmer ss = new SimpleStemmer();
            Assert.IsNotNull(ss);
            Assert.IsInstanceOfType(ss, typeof(SimpleStemmer));

        }

        [TestMethod]
        public void CanDetacheNounSuffxies()
        {
            SimpleStemmer ss = new SimpleStemmer();
            Assert.AreEqual<string>("dog", ss.FindStems("dogs", POS.NOUN)[0]);
            Assert.AreEqual<string>("boxeful", ss.FindStems("boxesful", POS.NOUN)[0]);
           
            //  "ses" -> "s"
            Assert.IsTrue( ss.FindStems("aaaases", POS.NOUN).Contains("aaaas"));
            //  "xes" -> "x"
            Assert.IsTrue(ss.FindStems("aaaaxes", POS.NOUN).Contains("aaaax"));
            //  "zes" -> "z"
            Assert.IsTrue(ss.FindStems("aaaazes", POS.NOUN).Contains("aaaaz"));
            //  "zes" -> "z"
            Assert.IsTrue(ss.FindStems("aaaazes", POS.NOUN).Contains("aaaaz"));
            //  "ches" -> "ch"
            Assert.IsTrue(ss.FindStems("aaaaches", POS.NOUN).Contains("aaaach"));
            //  "shes" -> "sh"
            Assert.IsTrue(ss.FindStems("aaaashes", POS.NOUN).Contains("aaaash"));
            //  "men" -> "man"
            Assert.IsTrue(ss.FindStems("aaaamen", POS.NOUN).Contains("aaaaman"));
            //  "ies" -> "y"
            Assert.IsTrue(ss.FindStems("aaaaies", POS.NOUN).Contains("aaaay"));
        }

        [TestMethod]
        public void CanDetacheVerbSuffixes()
        {
            SimpleStemmer ss = new SimpleStemmer();
            //  "s" -> ""
            Assert.IsTrue(ss.FindStems("aaaas", POS.VERB).Contains("aaaa"));
            //  "ies" -> "y"
            Assert.IsTrue(ss.FindStems("aaaaies", POS.VERB).Contains("aaaay"));
            //  "es" -> "e"
            Assert.IsTrue(ss.FindStems("aaaaes", POS.VERB).Contains("aaaae"));
            //  "es" -> ""
            Assert.IsTrue(ss.FindStems("aaaaes", POS.VERB).Contains("aaaa"));
            //  "ed" -> "e"
            Assert.IsTrue(ss.FindStems("aaaaed", POS.VERB).Contains("aaaae"));
            //  "ed" -> ""
            Assert.IsTrue(ss.FindStems("aaaaed", POS.VERB).Contains("aaaa"));
            //  "ing" -> "e"
            Assert.IsTrue(ss.FindStems("aaaaing", POS.VERB).Contains("aaaae"));
            //  "ing" -> ""
            Assert.IsTrue(ss.FindStems("aaaaing", POS.VERB).Contains("aaaa"));
        }

        [TestMethod]
        public void CanDetacheAdjectiveSuffixes()
        {
            SimpleStemmer ss = new SimpleStemmer();
            //  "er" -> ""
            Assert.IsTrue(ss.FindStems("aaaaer", POS.ADJECTIVE).Contains("aaaa"));
            //  "est" -> ""
            Assert.IsTrue(ss.FindStems("aaaaest", POS.ADJECTIVE).Contains("aaaa"));
            //  "er" -> "e"
            Assert.IsTrue(ss.FindStems("aaaaer", POS.ADJECTIVE).Contains("aaaae"));
            //  "est" -> "e"
            Assert.IsTrue(ss.FindStems("aaaaest", POS.ADJECTIVE).Contains("aaaae"));
        }
    }
}
